package org.aldar.bquest.logic.controller.entity;

import org.aldar.bquest.constants.IConstants;
import org.aldar.bquest.constants.LandscapeType;
import org.aldar.bquest.logic.controller.env.ProgressBar;
import org.aldar.bquest.logic.controller.level.LevelController;
import org.aldar.bquest.logic.controller.level.TimeLine;
import org.aldar.bquest.profile.GameProfile;
import org.aldar.bquest.screens.MainBoardScreen;
import org.aldar.bquest.util.Logger;
import org.aldar.bquest.util.TestUtil;
import org.andengine.entity.IEntity;
import org.andengine.entity.modifier.AlphaModifier;
import org.andengine.entity.modifier.DelayModifier;
import org.andengine.entity.modifier.IEntityModifier;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.entity.sprite.Sprite;
import org.andengine.util.modifier.IModifier;

/**
 * User: Daria
 * Date: 8/28/13 12:36 AM
 */
public class AttachingWalkAnimationModifierListener implements IEntityModifier.IEntityModifierListener, IConstants {

    private static final Logger LOG = new Logger(AttachingWalkAnimationModifierListener.class);

    @Override
    public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem) {
        LOG.i("start attach walk listener");
        LOG.i("starting walk animation");
        final int movingIndex = LevelController.getTimeLine().getCurrentMovingStateIndex();
        TestUtil.getInstance().updateText("Pending steps", "" + HeroAnimationController.getInstance().getStepsPending());
        HeroAnimationController.getInstance().startHeroWalkingAnimation();
        LOG.i("currentMovingStateIndex: " + movingIndex);
        LOG.i("currentItemIndex: " + LevelController.getTimeLine().getCurrentItemIndex());
        LOG.i("pendingSteps: " + HeroAnimationController.getInstance().getStepsPending());
        TestUtil.getInstance().updateText("movingI/currentI/totalI",
                LevelController.getTimeLine().getCurrentMovingStateIndex() + " / " +
                        LevelController.getTimeLine().getCurrentItemIndex() + " / " +
                        LevelController.getTimeLine().getLevelItems().size());
        if (movingIndex < LevelController.getTimeLine().getLevelItems().size()) {
            Sprite arrow = null;
            try {
                arrow = LevelController.getTimeLine().getArrows().get(movingIndex + 1);
            } catch (IndexOutOfBoundsException e) {
                //let arrow be null in this case
            }
            if (arrow != null /* && arrow.isVisible()*/) {
                arrow.registerEntityModifier(new AlphaModifier(0.3f, 1.0f, 0f, new IEntityModifier.IEntityModifierListener() {
                    @Override
                    public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem) {
                        LOG.i("arrows", "dissolving arrow for index" + (movingIndex + 1));
                    }

                    @Override
                    public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem) {
                    }
                }));
            }

            AnimatedSprite enemyImpAccounter = LevelController.getTimeLine().getEnemyMap().get(movingIndex + 1);
            if (enemyImpAccounter != null) { //hero has benn accountered with enemy!!!
                TileBoard.setEnemyOnBoard(enemyImpAccounter);
                LevelController.getTimeLine().getEnemyMap().remove(movingIndex + 1);
            }

            if (HeroAnimationController.getInstance().getHeroCurrentX() < CAMERA_WIDTH / 2
                    || LevelController.getTimeLine().getEndCastleBack().getX() + LevelController.getTimeLine().getEndCastleWidth() - TimeLine.LANDSCAPE_ITEM_WIDTH < CAMERA_WIDTH) {
                LOG.i("about to move hero right...");
                HeroAnimationController.getInstance().moveHeroStepRight();
            } else {
                LOG.i("moving landscapes left");
                TimeLine.moveLeft(LevelController.getTimeLine().getStartCastleBack());
                TimeLine.moveLeft(LevelController.getTimeLine().getStartCastleFront());
                TimeLine.moveLeft(LevelController.getTimeLine().getEndCastleBack());
                TimeLine.moveLeft(LevelController.getTimeLine().getEndCastleFront());
                for (int j = 0; j < LevelController.getTimeLine().getLevelItems().size(); j++) {
                    TimeLine.moveLeft(LevelController.getTimeLine().getLevelItems().get(j).getLandscapeSprite());
                    TimeLine.moveLeft(LevelController.getTimeLine().getArrows().get(j));
                    TimeLine.moveLeft(LevelController.getTimeLine().getEnemyMap().get(j));
                    TimeLine.moveLeft(LevelController.getTimeLine().getLevelItems().get(j).getTownNote());
                    TimeLine.moveLeft(LevelController.getTimeLine().getLevelItems().get(j).getLsBasementSprite());
                }
            }
            LevelController.getTimeLine().increaseCurrentMovingStateIndex();
            ProgressBar.setPosition(LevelController.getTimeLine().getCurrentMovingStateIndex());
        } else {
            LOG.i("End of the level has been reached! should never get here!! check your code");
            //return false;
        }


    }

    @Override
    public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem) {
        LOG.i("finished attach walk listener");
        if (LevelController.getTimeLine().getCurrentMovingStateIndex() >= LevelController.getTimeLine().getLevelItems().size() || LevelController.getCurrentLevelState() == LevelController.LevelState.FINISHED) {
            LOG.i("reached level finish!");
            //level done!
            MainBoardScreen.getScm().setBgTouchAreas(false, true);
            /*ParticleUtil.makeParticleSpiral(3f,
                    CAMERA_WIDTH / 2, CAMERA_HEIGHT / 2,
                    CAMERA_WIDTH / 2,
                    0.2f,
                    10,
                    50,
                    ResourceManager.getInstance().getParticleRegion(),
                    MainBoardScreen.getInstanceEngine(),
                    MainBoardScreen.getScm().getBonusLayer()
            );*/


            HeroAnimationController.getInstance().moveHeroIntoCastle();
        } else {
            LandscapeType walkingLsType = LevelController.getTimeLine().getLevelItems().get(LevelController.getTimeLine().getCurrentMovingStateIndex()).getLandscapeType();
            LandscapeType prevLsType = LevelController.getTimeLine().getLevelItems().get(LevelController.getTimeLine().getCurrentMovingStateIndex() - 1).getLandscapeType();
            boolean isCurrentTown = walkingLsType.allowsConcerts() == true;

            if (walkingLsType.allowsConcerts() == true && prevLsType.allowsConcerts() == false) {
                //entered town!
                int reachedTownIndex = GameProfile.getCurrentLevelProfile().getReachedTownIndex() + 1;
                int remainingConcerts = GameProfile.getCurrentLevelProfile().getRemainingConcertsByTown().get(reachedTownIndex);
                GameProfile.getCurrentLevelProfile().setReachedTownIndex(reachedTownIndex);
                if (remainingConcerts > 0) {
                    TileBoard.replaceAllAbilitiesForLandscape(isCurrentTown);
                }


            } else if ((walkingLsType.allowsConcerts() == false && prevLsType.allowsConcerts() == true)) {
                TileBoard.replaceAllAbilitiesForLandscape(isCurrentTown);
                //left town!
                //???? not clear yet what to do here..
            }


            if (HeroAnimationController.getInstance().getStepsPending() > 0 && HeroAnimationController.getInstance().getAbilityActionRequested() == null) {
                LOG.i("pending steps found = " + HeroAnimationController.getInstance().getStepsPending());
                MainBoardScreen.getScm().getHeroLayer().registerEntityModifier(new DelayModifier(HeroAnimationController.HERO_STEP_DURATION, new AttachingWalkAnimationModifierListener()));
                HeroAnimationController.getInstance().decreaseStepsPending(1);
            } else {
                HeroAnimationController.getInstance().setWalking(false);
                LevelController.getTimeLine().setCurrentLandscapeReached(true);
                LOG.i("no pending steps, stop animation");
                if (HeroAnimationController.getInstance().getAbilityActionRequested() != null) {
                    //set current landscape to last reached landscape - cancel further proceedence
                    LevelController.getTimeLine().setCurrentItemIndex(LevelController.getTimeLine().getCurrentMovingStateIndex());
                    //hide arrows
                    for (AnimatedSprite arrow : LevelController.getTimeLine().getArrows()) {
                        arrow.setVisible(false);
                    }
                    LandscapeType currentLsType = LevelController.getTimeLine().getCurrentLandscape().getLandscapeType();
                    GameProfile.getCurrentLevelProfile().setLastStopLandscape(currentLsType);
                    Runnable abilityRun = HeroAnimationController.getInstance().getAbilityActionRequested();
                    HeroAnimationController.getInstance().setAbilityActionRequested(null);
                    abilityRun.run();

                } else {
                    HeroAnimationController.getInstance().startHeroIdleAnimation();
                    LandscapeType currentLsType = LevelController.getTimeLine().getCurrentLandscape().getLandscapeType();
                    GameProfile.getCurrentLevelProfile().setLastStopLandscape(currentLsType);
                }
                //FIXME
                /*
                int availableMoves = AvailableMovesCounter.checkAvailableMoves();
                LOG.i("available moves = " + availableMoves);
                if (availableMoves <= 0) {
                    TileBoard.recreateHopelessTileBoard();
                }
                */
            }
        }
    }
}
